// dio_utils.dart
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:jtlf/common/consts.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:retry/retry.dart';

class DioUtils {
  static final DioUtils _instance = DioUtils._internal();
  late Dio _dio;

  // 单例模式
  factory DioUtils() => _instance;

  DioUtils._internal() {
    _initDio();
  }

  void _initDio() {
    _dio = Dio(BaseOptions(
      baseUrl: serverUrl, // 替换为你的 API 地址
      connectTimeout: const Duration(seconds: 10),
      receiveTimeout: const Duration(seconds: 10),
      responseType: ResponseType.bytes, // 设置响应二进制数据，默认是文本数据
    ));

    // 添加拦截器
    _dio.interceptors.add(_authInterceptor());
  }

  Interceptor _authInterceptor() {
    return InterceptorsWrapper(
      onRequest: (options, handler) async {
        // 从 SharedPreferences 获取认证信息
        final prefs = await SharedPreferences.getInstance();
        final token = prefs.getString('auth_token');
        final userId = prefs.getString('user_id');
        final tenantId = prefs.getString('tenant_id');

        // 设置请求头
        options.headers.addAll({
          'Content-Type': 'application/x-protobuf; charset=UTF-8',
          if (token != null) 'Authorization': 'Bearer $token',
          if (token != null) 'tokenId': token, // 这个key会变成tokenid，要不就用横线分割，http规范
          if (userId != null) 'userId': userId,
          if (tenantId != null) 'tenantId': tenantId,
        });

        return handler.next(options);
      },
      onError: (error, handler) async {
        // 统一错误处理（例如 token 过期）
        if (error.response?.statusCode == 401) {
          await _handleTokenExpired();
        }
        return handler.next(error);
      },
    );
  }

  Future<void> _handleTokenExpired() async {
    // 执行刷新 token 或跳转登录页面的逻辑
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('auth_token');
    if (kDebugMode) {
      print('Token expired, please re-login');
    }
  }

  // 封装 GET 请求
  Future<Response> get(
      String path, {
        Map<String, dynamic>? queryParams,
        Options? options,
      }) async {
    return await _dio.get(
      path,
      queryParameters: queryParams,
      options: options
    );
  }

  Future<Response> getWithRetry(String path) async {
    return await retry(
          () => _dio.get(path),
      retryIf: (e) => e is DioException && e.type != DioExceptionType.cancel,
    );
  }


  // 封装 POST 请求
  Future<Response> post(
      String path, {
        dynamic data,
        Map<String, dynamic>? queryParams,
        Options? options,
      }) async {
    return await _dio.post(
      path,
      data: data,
      queryParameters: queryParams,
      options: options
    );
  }

  // 封装 PUT 请求
  Future<Response> put(
      String path, {
        dynamic data,
        Map<String, dynamic>? queryParams,
        Options? options,
      }) async {
    return await _dio.put(
      path,
      data: data,
      queryParameters: queryParams,
      options: options
    );
  }

  // 封装 DELETE 请求
  Future<Response> delete(
      String path, {
        Map<String, dynamic>? queryParams,
        Options? options,
      }) async {
    return await _dio.delete(
      path,
      queryParameters: queryParams,
      options: options
    );
  }

  Future<Response> uploadFile(String path, String filePath) async {
    final formData = FormData.fromMap({
      'file': await MultipartFile.fromFile(filePath),
    });
    return _dio.post(path, data: formData);
  }

}
